package com.telit.common.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.telit.common.enums.ResultCode;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.token.User;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @Auther amy
 * @Describe
 */
public class JwtTokenUtils {

    /** 过期时间（单位毫秒） */
    public static final long EXPIRE_MILLISECOND = 100 * 60 * 60 * 1000;

    /** 签名密钥 */
    public static final String SECRET = "Telit@123";

    /** 请求头令牌KEY */
    public static final String TOKEN_KEY = "Authorization";

    /**
     * token分割符
     */
    public static final String TOKEN_SPLIT = "Bearer ";

    public static final String TOKEN_PARAM_ID = "id";
    public static final String TOKEN_PARAM_NAME = "user_name";
    // todo 可能根据新统一平台变更
    public static final String TOKEN_PARAM_DISTRICT_CODE = "regionCode";
    public static final String TOKEN_PARAM_REALNAME = "real_name";
    public static final String TOKEN_PARAM_MOBILE = "mobile";
    public static final String TOKEN_PARAM_CUSTOMERID = "customerId";
//    public static final String TOKEN_PARAM_ORGID= "orgId";
//    public static final String TOKEN_PARAM_UNIT= "unit";

    /**
     * 获取载荷
     * @param token 加密签名
     * @param key 载荷名称
     * @return 载荷值
     */
    private static String getClaim(String token, String key) {
        if(StringUtils.hasText(token)){
            return JWT.decode(token).getClaim(key).asString();
        }
        throw new ForestBaseException(ResultCode.AUTHC_ILLEGAL.getCode(),"token为空,认证失败");
    }

    /**
     * 获取id
     * @return
     */
    public static Long getId(){
        User user = getUser(ServletUtils.getRequest());
        return user == null ? null: user.getId();
    }

    public static String getName() {
        User user = getUser(ServletUtils.getRequest());
        return user == null ? null : user.getUserName();
    }

    public static String getRealName() {
        User user = getUser(ServletUtils.getRequest());
        return user == null ? null : user.getRealName();
    }

    /**
     * token里目前已经没有districtCode信息
     */
    @Deprecated
    public static String getDistrictCode() {
        User user = getUser(ServletUtils.getRequest());
        return user == null ? null : user.getRegionCode();
    }

    /**
     * token里目前已经没有mobile信息
     */
    @Deprecated
    public static String getMobile() {
        User user = getUser(ServletUtils.getRequest());
        return user == null ? null : user.getMobile();
    }

    /**
     * 获取token
     *
     * @param request
     *
     * @return
     */
//    public static String getToken(HttpServletRequest request){
//        String accessTokenFromHeader = request.getHeader(TOKEN_KEY);
//        if(StringUtils.isEmpty(accessTokenFromHeader)){
//            throw new ForestBaseException(ResultCode.AUTHC_ILLEGAL.getCode(),"token为空,认证失败");
//        }
//        return accessTokenFromHeader;
//    }

    public static String getToken(HttpServletRequest request) {
        String authorization = request.getHeader(JwtTokenUtils.TOKEN_KEY);
        if (StrUtil.isEmpty(authorization)) {
            throw new ForestBaseException("token不能为空");
        }
        return StrUtil.subAfter(authorization, JwtTokenUtils.TOKEN_SPLIT, true);
    }

    public static User getUser(HttpServletRequest request) {
        //从Header中获取用户信息
        if(request == null){
            return null;
        }
        String userStr = request.getHeader("user");
        if (StrUtil.isNotEmpty(userStr)) {
            try {
                userStr = URLDecoder.decode(userStr, "utf-8");
            } catch (UnsupportedEncodingException e) {
                throw new ForestBaseException("解码获取登录用户信息异常");
            }
            JSONObject userJsonObject = new JSONObject(userStr);
            User user = new User();
            user.setId(Convert.toLong(userJsonObject.get("id")));
            user.setUserName(userJsonObject.getStr("user_name"));
            user.setMobile(userJsonObject.getStr("mobile"));
            user.setCustomerId(Convert.toLong(userJsonObject.get("customerId")));
            user.setDeptCode(Convert.toLong(userJsonObject.get("deptCode")));
            user.setRegionCode(userJsonObject.getStr("regionCode"));
            user.setRealName(userJsonObject.getStr("realName"));
            return user;
        }
        return null;
    }

    /**
     * 加密
     * @param username
     * @param map
     * @return
     */
    public static String sign(String username, Map<String, String> map) {
        Date nows = new Date();
        Date expires = new Date(System.currentTimeMillis() + EXPIRE_MILLISECOND);
        JWTCreator.Builder builder = JWT.create();
        builder.withAudience(username);
        if (map != null && map.keySet().size() > 0) {
            for (String key : map.keySet()) {
                builder.withClaim(key, map.get(key));
            }
        }
        builder.withIssuedAt(nows);
        builder.withExpiresAt(expires);
        return builder.sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 生成测试的token
     * @param args
     */
    public static void main(String[] args) throws UnsupportedEncodingException {
        Map<String, String> map  = new HashMap<>();
        map.put("id","18");
        map.put("username","amy");
        map.put("loginStatus","1");
        map.put("realname","艾米");
        map.put("districtCode","3201");
        String token = sign("amy",map);
        System.out.println(token);
        String tokenStr = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6Im5hbmppbmdmb3Jlc3RyeSIsInVzZXJfbmFtZSI6Im5qMiIsIm1vYmlsZSI6IiIsImF1dGhvcml0aWVzIjpbIk5KX0ZTRFoiXSwiY2xpZW50X2lkIjoibmFuamluZ2ZvcmVzdHJ5IiwicmVhbE5hbWUiOiJuajIiLCJsYXN0TG9naW5UaW1lIjoiIiwicmVnaW9uQ29kZSI6IjMyMDExMSIsInNjb3BlIjpbImFsbCJdLCJjdXN0b21lcklkIjoxNDUwMzU3NzY4OTk2MzA2OTQ2LCJpZCI6NiwiZXhwIjoxNjM1MTMxMTExLCJqdGkiOiJlNjJlMmEzNC1lNGRmLTQ3NTUtYTQ1Yi1jMzk0MDliYTQ4YjMiLCJkZXB0Q29kZSI6NH0.Ejt3KcUlyOMX0MZjBlR4A4t8J5eGNqCyZPoA1WT1v7Jp8tNQZYA8kjPOVcS89uKogWiaq0BE2nxqvN6ZXNlbkmpixgWV_yzRPiClt2NgYwLvxAYsI8AfeR8ZoiOoYXDqqcKmTjkK_UBS97kQSh_ATnxbkklVzh45wPVeTJpxrWbDTTK-VWdOTrsIPSJ62r0p1F3camI5_SWiFoDyPxGqPVpc68FCGNviSJoO2SphwrUfFGjlG-Xrr70S31DBh_LVzVPfqJuz0kQuzB1eraHk_a4mehg5pPMwKzomsXYzItHEgNiRdvXwDZFKuH4Hwvklv77kpmPru-affJLnRMVMrA";
        String id = JSON.toJSONString(getClaim(tokenStr,"id"));
        String lastLoginTime = JSON.toJSONString(getClaim(tokenStr,"lastLoginTime"));
        System.out.println(id);
//        String token = JSON.toJSONString(JWT.decode(tokenStr).getClaim("lastLoginTime"));
//        System.out.println(JWT.decode(tokenStr).getClaim("lastLoginTime").asString());
    }


}
